# -*- coding: utf-8 -*-
'''
Created on 09/nov/2009

@author: sax
'''

from django.core.exceptions import PermissionDenied
from django.db import models, models, transaction
from django.forms.formsets import all_valid
from django.forms.models import BaseInlineFormSet, modelform_factory, modelformset_factory, inlineformset_factory
from django.utils.encoding import force_unicode
from django.utils.functional import curry, update_wrapper
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _, ugettext_lazy
from xadmin import helpers
from xadmin.options.strategies import Strategy

import logging
#from copy import copy
#from django import forms, forms, template
#from django.contrib.admin import helpers, widgets
#from django.contrib.admin.util import unquote, flatten_fieldsets, get_deleted_objects, model_ngettext, model_format_dict
#from django.contrib.contenttypes.models import ContentType
#from django.core.urlresolvers import reverse, resolve, NoReverseMatch
#from django.db.models.fields import BLANK_CHOICE_DASH
from django.http import Http404, HttpResponse, HttpResponseRedirect
#from django.shortcuts import get_object_or_404, render_to_response
#from django.template.context import Context
#from django.template.loader import get_template
#from django.utils.datastructures import SortedDict
#from django.utils.html import escape
#from django.utils.text import capfirst, get_text_list

LOGGER = logging.getLogger('xadmin.xamodeladmin')

from xadmin.options.strategies.edit import EditStrategy
class AddStrategy(EditStrategy):
    
    def __set__(self, owner, value):
        super(AddStrategy, self).__set__(owner, value)
        owner.add_view = self.add_view

    
    def add_view(self, request, form_url='', extra_context=None):
        "The 'add' admin view for this model."
        model = self.model
        opts = model._meta

        if not self._owner.has_add_permission(request):
            raise PermissionDenied
        
        self._owner.mode = self._owner._MODE_ADD

        ModelForm = self.get_form(request)
        formsets = []
        if request.method == 'POST':
            form = ModelForm(request.POST, request.FILES)
            if form.is_valid():
                form_validated = True
                new_object = self._owner.save_form(request, form, change=False)
            else:
                form_validated = False
                new_object = self.model()
            prefixes = {}
            for FormSet in self.get_formsets(request, None):
                prefix = FormSet.get_default_prefix()
                prefixes[prefix] = prefixes.get(prefix, 0) + 1
                if prefixes[prefix] != 1:
                    prefix = "%s-%s" % (prefix, prefixes[prefix])
                formset = FormSet(data=request.POST, files=request.FILES,
                                  instance=new_object, prefix=prefix,
                                  save_as_new=request.POST.has_key("_saveasnew"),
                                  )
                formsets.append(formset)
                
            if all_valid(formsets) and form_validated:
                self._owner.save_model(request, new_object, form, change=False)
                form.save_m2m()
                for formset in formsets:
                    self.save_formset(request, form, formset, change=False)

                self._owner.log_addition(request, new_object)
                return self.response_add(request, new_object)
        else:
            # Prepare the dict of initial data from the request.
            # We have to special-case M2Ms as a list of comma-separated PKs.
            initial = dict(request.GET.items())
            for k in initial:
                try:
                    f = opts.get_field(k)
                except models.FieldDoesNotExist:
                    continue
                if isinstance(f, models.ManyToManyField):
                    initial[k] = initial[k].split(",")
            form = ModelForm(initial=initial)
            prefixes = {}
            for FormSet in self.get_formsets(request):
                prefix = FormSet.get_default_prefix()
                prefixes[prefix] = prefixes.get(prefix, 0) + 1
                if prefixes[prefix] != 1:
                    prefix = "%s-%s" % (prefix, prefixes[prefix])
                formset = FormSet(instance=self.model(), prefix=prefix)
                formsets.append(formset)

        adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields)
#        media = self._owner.media + adminForm.media

        inline_admin_formsets, media = self.get_inline_admin_formsets(request, adminForm, formsets, None)
#        inline_admin_formsets = []
#        for inline, formset in zip(self.inline_instances, formsets):
#            fieldsets = list(inline.get_fieldsets(request))
#            inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets)
#            inline_admin_formsets.append(inline_admin_formset)
#            media = media + inline_admin_formset.media

            
        context = {
            'title': _('Add %s') % force_unicode(opts.verbose_name),
            'adminform': adminForm,
            'is_popup': request.REQUEST.has_key('_popup'),
            'show_delete': False,
            'media': mark_safe(media),
            'inline_admin_formsets': inline_admin_formsets,
            'errors': helpers.AdminErrorList(form, formsets),
            'root_path': self.admin_site.root_path,
            'app_label': opts.app_label,
        }
        context.update(extra_context or {})
        return self.render_change_form(request, context, form_url=form_url, add=True)
    add_view = transaction.commit_on_success(add_view)

    def response_add(self, request, obj, post_url_continue='../%s/'):
        """
        Determines the HttpResponse for the add_view stage.
        """
        opts = obj._meta
        pk_value = obj._get_pk_val()

        msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj)}
        # Here, we distinguish between different save types by checking for
        # the presence of keys in request.POST.
        if request.POST.has_key("_continue"):
            self._owner.message_user(request, msg + ' ' + _("You may edit it again below."))
            if request.POST.has_key("_popup"):
                post_url_continue += "?_popup=1"
            return HttpResponseRedirect(post_url_continue % pk_value)

        if request.POST.has_key("_popup"):
            return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \
                # escape() calls force_unicode.
                (escape(pk_value), escape(obj)))
        elif request.POST.has_key("_addanother"):
            self._owner.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
            return HttpResponseRedirect(request.path)
        else:
            self._owner.message_user(request, msg)

            # Figure out where to redirect. If the user has change permission,
            # redirect to the change-list page for this object. Otherwise,
            # redirect to the admin index.
            if self._owner.has_change_permission(request, None):
                post_url = '../'
            else:
                post_url = '../../../'
            return HttpResponseRedirect(post_url)

    
    
    